package com.zretc.friend.service;


import com.zretc.api.pojo.User;
import com.zretc.friend.mapper.FriendMapper;
import com.zretc.friend.model.Friend;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.stream.Collectors;

@Service
public class FriendService {

    @Autowired
    private FriendMapper friendMapper;

    public List<Friend> getFriends(Integer userId) {
        return friendMapper.findByUserId(userId);
    }

    public List<Friend> getBlocked(Integer userId) {
        return friendMapper.findByBlockedId(userId);
    }

    public User findUserById(Integer userId) {
        return friendMapper.findUserById(userId);
    }


    public void followUser(Integer userId, Integer friendId) {
        Friend existingFriend = friendMapper.findFriend(userId, friendId);

        if (existingFriend == null) {
            Friend newFriend = new Friend();
            newFriend.setUserId(userId);
            newFriend.setFriendId(friendId);
            newFriend.setStatus("following");
            friendMapper.addFriend(newFriend);

            // Check if the other user is also following the current user
            Friend reciprocalFriend = friendMapper.findFriend(friendId, userId);
            if (reciprocalFriend != null && "following".equals(reciprocalFriend.getStatus())) {
                // Update both users' status to 'friend'
                friendMapper.updateFriendStatus(userId, friendId, "friend");
                friendMapper.updateFriendStatus(friendId, userId, "friend");
            }
        } else {
            // If already exists but not 'friend', update the status
            if (!"friend".equals(existingFriend.getStatus())) {
                existingFriend.setStatus("following");
                friendMapper.updateFriendStatus(userId, friendId, "following");

                // Check if the other user is also following the current user
                Friend reciprocalFriend = friendMapper.findFriend(friendId, userId);
                if (reciprocalFriend != null && "following".equals(reciprocalFriend.getStatus())) {
                    // Update both users' status to 'friend'
                    friendMapper.updateFriendStatus(userId, friendId, "friend");
                    friendMapper.updateFriendStatus(friendId, userId, "friend");
                }
            }
        }
    }

    public void unfollowUser(Integer userId, Integer friendId) {
        Friend existingFriend = friendMapper.findFriend(userId, friendId);
        if (existingFriend != null) {
            if ("friend".equals(existingFriend.getStatus())) {
                // Update to following if only one way
                friendMapper.updateFriendStatus(userId, friendId, "following");

                // Also update the reciprocal relationship
                friendMapper.updateFriendStatus(friendId, userId, "following");
            } else {
                // Just delete the relationship
                friendMapper.deleteFriend(userId, friendId);
            }
        }
    }

    public void blockUser(Integer userId, Integer friendId) {
        Friend existingFriend = friendMapper.findFriend(userId, friendId);
        if (existingFriend == null) {
            Friend newFriend = new Friend();
            newFriend.setUserId(userId);
            newFriend.setFriendId(friendId);
            newFriend.setStatus("blocked");
            friendMapper.addFriend(newFriend);
        } else {
            existingFriend.setStatus("blocked");
            friendMapper.updateFriendStatus(userId, friendId, "blocked");
        }
    }

    public List<Friend> recommendFriends(Integer userId) {
        // A simple recommendation algorithm, e.g., friends of friends
        List<Friend> following = friendMapper.findFollowingByUserId(userId);
        Set<Integer> recommendedIds = new HashSet<>();
        for (Friend follow : following) {
            List<Friend> friendsOfFollow = friendMapper.findByUserId(follow.getFriendId());
            for (Friend fof : friendsOfFollow) {
                if (!fof.getFriendId().equals(userId) && !following.contains(fof)) {
                    recommendedIds.add(fof.getFriendId());
                }
            }
        }
        return recommendedIds.stream().map(id -> {
            Friend friend = new Friend();
            friend.setUserId(userId);
            friend.setFriendId(id);
            return friend;
        }).collect(Collectors.toList());
    }
}
